import BaseOAuthProvider from "./base-provider";
import type { OAuthConfig } from "./base-provider";
import axios from 'axios';
import { OAuthUserInfo } from "@/service/oauthService";
import crypto from 'crypto';

/**
 * Twitter(X) OAuth Provider
 * 实现 Twitter/X OAuth 2.0 Authorization Code Flow with PKCE
 * 基于 X API v2 认证流程
 */
class TwitterProvider extends BaseOAuthProvider {
    authUrl: string;
    tokenUrl: string;
    userInfoUrl: string;

    constructor(config: OAuthConfig) {
        super(config);
        this.authUrl = 'https://x.com/i/oauth2/authorize';
        this.tokenUrl = 'https://api.x.com/2/oauth2/token';
        this.userInfoUrl = 'https://api.x.com/2/users/me';
    }

    /**
     * 生成授权URL
     * Twitter OAuth 2.0 使用 PKCE 扩展
     */
    generateAuthUrl(state?: string): string {
        const params = new URLSearchParams({
            response_type: 'code',
            client_id: this.clientId,
            redirect_uri: this.redirectUri,
            scope: this.scopes.join(' '),
            state: state || 'default_state',
            code_challenge: 'challenge', // 在生产环境中应使用随机字符串
            code_challenge_method: 'S256'
        });

        return `${this.authUrl}?${params.toString()}`;
    }

    /**
     * 交换授权码获取访问令牌
     * 使用 X API v2 OAuth 2.0 token endpoint
     */
    async exchangeCodeForTokens(code: string) {
        try {
            const params = new URLSearchParams({
                code: code,
                grant_type: 'authorization_code',
                client_id: this.clientId,
                redirect_uri: this.redirectUri,
                code_verifier: 'challenge' // 应与 code_challenge 对应
            });

            const response = await axios.post(this.tokenUrl, params, {
                headers: {
                    'Content-Type': 'application/x-www-form-urlencoded'
                },
                timeout: 10000 // 10秒超时
            });

            const data = response.data;

            // 检查是否有错误
            if (data.error) {
                throw new Error(`Twitter OAuth error: ${data.error_description || data.error}`);
            }

            // 验证响应数据
            if (!data.access_token) {
                throw new Error('No access token received from Twitter');
            }

            return data;
        } catch (error: any) {
            if (error.response) {
                // Twitter API返回的错误
                const errorData = error.response.data;
                let errorMessage = error.message;

                if (errorData.error) {
                    errorMessage = errorData.error_description || errorData.error;
                } else if (errorData.detail) {
                    errorMessage = errorData.detail;
                }

                throw new Error(`Twitter token exchange failed: ${errorMessage} (HTTP ${error.response.status})`);
            } else if (error.request) {
                // 网络错误
                throw new Error(`Twitter token exchange failed: Network error - ${error.message}`);
            } else {
                // 其他错误
                throw new Error(`Twitter token exchange failed: ${error.message}`);
            }
        }
    }

    /**
     * 获取用户信息
     * 使用 X API v2 users/me endpoint
     */
    async getUserInfo(accessToken: string) {
        try {
            // 获取用户基本信息
            const response = await axios.get(this.userInfoUrl, {
                params: {
                    'user.fields': 'id,name,username,profile_image_url,description,public_metrics,verified,created_at'
                },
                headers: {
                    'Authorization': `Bearer ${accessToken}`,
                    'User-Agent': 'OAuth-App' // X API 建议添加 User-Agent
                },
                timeout: 10000
            });

            const userData = response.data;

            // 验证响应数据
            if (!userData.data || !userData.data.id) {
                throw new Error('Invalid user info received from Twitter');
            }

            return userData.data;
        } catch (error: any) {
            if (error.response) {
                // Twitter API返回的错误
                const status = error.response.status;
                const errorData = error.response.data;

                if (status === 401) {
                    throw new Error('Twitter user info fetch failed: Invalid or expired access token');
                } else if (status === 403) {
                    throw new Error('Twitter user info fetch failed: Forbidden - insufficient permissions');
                } else if (status === 429) {
                    throw new Error('Twitter user info fetch failed: Rate limit exceeded');
                } else {
                    const detail = errorData.detail || errorData.error || 'Unknown error';
                    throw new Error(`Twitter user info fetch failed: ${detail} (HTTP ${status})`);
                }
            } else if (error.request) {
                // 网络错误
                throw new Error('Twitter user info fetch failed: Network error');
            } else {
                // 其他错误
                throw new Error(`Twitter user info fetch failed: ${error.message}`);
            }
        }
    }

    /**
     * 处理用户数据，转换为统一格式
     * Twitter API v2 返回的用户数据格式处理
     */
    processUserData(userInfo: any): OAuthUserInfo {
        // 处理用户姓名
        let name = userInfo.name;
        if (!name && userInfo.username) {
            name = userInfo.username; // Twitter 用户名作为备选
        } else if (!name) {
            name = 'Twitter User';
        }

        // Twitter API v2 不直接提供邮箱，使用用户名生成伪邮箱
        // 注意：要获取真实邮箱需要申请特殊权限和 users.email scope
        const email = `${userInfo.username}@twitter.local`;

        // 处理头像URL
        let avatar = userInfo.profile_image_url;
        if (avatar) {
            // Twitter 头像URL默认是 _normal 尺寸，可以替换为更大尺寸
            avatar = avatar.replace('_normal', '_400x400');
        }

        return {
            id: userInfo.id.toString(), // 确保ID是字符串
            email: email, // 伪邮箱，实际项目中可能需要其他方式处理
            name: name,
            avatar: avatar || undefined
        };
    }
}

export default TwitterProvider;
